#include "ListeType.h"
#include <stdlib.h>
#include <stdio.h>

/* On a ici déclaré des variables globales à l'ensemble du fichier. Elle vont permettre de connaitre le nombre de tour,
* d'upgrades et de stocker l'ensemble des caractéristiques qui sont lues sur un fichier au départ. Dans l'idéal, il faudrait
* que ces données viennent elles aussi du fichier. Cette fonctionalité sera ajoutée plus tard... */
const int nbtours=4;
const int nbup=4;
int caracteristiques[nbtours*nbup][5];


// déclaration des fonctions internes au module :
Stype* rempli_listedetype (Stype* listtyp, int ligne);
void miseazero (Stype* listtyp);
void rempli_tabcaracteristiques(int tab[nbtours*nbup][5]);


/* Procédure interne au module qui va simplement permettre d'initialiser à NULL les pointeurs d'un nouvel élément liste de
 * types (le pointeur sur un type et le pointeur sur la liste de type suivante).
 * Elle prend en parametre une pointeur sur une structure liste de types. */
void miseazero (Stype* listtyp)
{
	(*listtyp).ptype=NULL;
	(*listtyp).ptypesuiv=NULL;
}

/* Procédure qui va permettre de remplir, en début de jeu, le tableau de caractéristique déclaré en variable globale à
 * partir du fichier contenant les caractéristiques.
 * Elle prend en parametre un tableau de taille (nb d'elements*nb d'upgrades)*5 */
void rempli_tabcaracteristiques(int tab[nbtours*nbup][5])
{
	// déclaration des variables locales
	int i;
	FILE* fichier = NULL;
	// ouverture du fichier contenant les caractéristiques des différents types
    fichier = fopen("Types.txt", "r");
	// si l'ouverture s'est bien passée
    if (fichier != NULL)
    {
		// on remplit le tableau grace à une boucle for :
		for (i=0;i<nbtours*nbup;i++)
		{
			fscanf(fichier, "%d %d %d %d %d", &tab[i][0], &tab[i][1], &tab[i][2], &tab[i][3], &tab[i][4]);
		}
		// une fois qu'on a terminé de lire le fichier, on n'oublie pas de le refermer
        fclose(fichier);
    }
}

/* Fonction qui  va permettre de remplir la liste de types à partir du tableau (qui vient lui meme du fichier de base).
 * Elle prend en parametre un pointeur sur une liste de types et un entier qui correspond à la ligne du tableau qu'on va lire.
 * Elle renvoie un pointeur sur une structure type.
 * Cette fonction rempli en fait à chaque appel les caractéristiques d'un et d'un seul type. IL faudra l'appeler X fois si
 * on a X types différents (sachant qu'un type correspond à une tour et une upgrade). */
Stype* rempli_listedetype (Stype* listtyp, int ligne)
{
	// On commence par créer et reserver l'emplacement mémoire pour le type que l'on va remplir.
	(*listtyp).ptype=new Stypetour;
	// On initialise afin d'être sûr qu'il n'y aura pas de surprises.
	init_typetour((*listtyp).ptype);
	// On modifie le type avec les caractéristiques contenues dans le tableau à la ligne correspondante.
	set_all((*listtyp).ptype, caracteristiques[ligne][0], caracteristiques[ligne][1], caracteristiques[ligne][2], caracteristiques[ligne][3], caracteristiques[ligne][4]);
	// si on n'est pas à la fin du tableau
	if (ligne<nbtours*nbup)
	{
		// on créé le type suivant que l'on initialise.
		(*listtyp).ptypesuiv=new Stype;
		miseazero((*listtyp).ptypesuiv);
	}
	else
	// Sinon on ne fait que mettre à NULL la valeur du pointeur sur suivant.
	{
		(*listtyp).ptypesuiv=NULL;
	}
	// dans tout les cas, on renvoie le pointeur sur l'element de la liste de type suivant.
	return ((*listtyp).ptypesuiv);
}

/* Procédure qui va permettre d'initialiser la liste de types.
 * Elle prend en parametre un pointeur sur une liste de types.
 * C'est cette fonction qui sera appelée de l'exterieur et qui appellera en cascade toutes celles vues précédemment. */
void init_listetype (Stype* listtyp)
{
	// déclaration d'un entier i qui va servir pour la boucle for.
	int i;
	// on commence par remplir le tableau de caractéristiques
	rempli_tabcaracteristiques(caracteristiques);
	// on créé un pointeur temporaire sur la liste de type qui va permettre de se déplacer à l'interieur de la liste de types
	Stype* pourincrementer;
	// et on lui donne la valeur de départ
	pourincrementer=listtyp;
	// puis on appel la fonction de remplissage d'un type donné tant que i est inférieur au nombre de types et donc à la
	// ligne du tableau caractéristiques
	for (i=0;i<nbtours*nbup;i++)
	{
		pourincrementer=rempli_listedetype (pourincrementer, i);
	}
}

/* Procédure qui va permettre de vider l'ensemble de la liste.
 * Elle prend en parametre un pointeur sur une liste de types.
 * (RECURSIVE) */
void vider_listetype (Stype* listtyp)
{
	// Si le pointeur sur la liste de type suivante est nul alors on rappelle récursivement la fonction
	if ((*listtyp).ptypesuiv!=NULL)
	{
		vider_listetype ((*listtyp).ptypesuiv);
	}
	// sinon on efface d'abord le pointeur sur le type puis le pointeur sur la liste de type.
	delete ((*listtyp).ptype);
	(*listtyp).ptype=NULL;
	delete (listtyp);
	listtyp=NULL;
}


/* Fonction accesseur qui va permettre d'acceder a la liste de type.
 * Elle prend en parametre un pointeur sur une liste de type qui ne pourra etre modifié et un entier qui correspond au
 * numéro du type que l'on recherche.
 * Elle renvoie un pointeur sur la structure type correspondant.
 * (RECURSIVE) */
Stypetour* get_listetype (const Stype* listtyp, int numtypAtrouver)
{
	// si le numero du type en cours correspond à celui que l'on recherche, on renvoie alors le pointeur sur le type en cours
	if (((*(*listtyp).ptype).numero)==numtypAtrouver)
	{
		return ((*listtyp).ptype);
	}
	// sinon on rappelle la fonction sur l'élément suivant
	else
	{
		return (get_listetype (((*listtyp).ptypesuiv),numtypAtrouver));
	}
}
		


